package com.dongzili.common.disruptor.config;

import com.dongzili.common.disruptor.entity.MessageEvent;
import com.dongzili.common.disruptor.factory.MessageEventFactory;
import com.dongzili.common.disruptor.handler.MessageEventHandler;
import com.lmax.disruptor.*;
        import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

@Configuration
public class MqConfig {

    private final ThreadFactory virtualThreadFactory = Thread.ofVirtual().name("disruptor-vt-",0L).factory();
    // 创建基于虚拟线程的ExecutorService
    @Bean("disruptorExecutor")
    public ExecutorService disruptorExecutor() {
//        ThreadFactory factory = Thread.ofVirtual().factory();
        return Executors.newThreadPerTaskExecutor(virtualThreadFactory);
    }

    @Bean("MessageEvent")
    public <T> RingBuffer<MessageEvent<T>> messageVoRingBuffer(
            ExecutorService disruptorExecutor,
            MessageEventHandler<T> messageEventHandler) {

        // 指定ringbuffer大小，必须为2的N次方
        int bufferSize = calculateRingBufferSize();

        // 创建Disruptor实例，使用虚拟线程执行器
        Disruptor<MessageEvent<T>> disruptor = new Disruptor<>(
                new MessageEventFactory<>(),
                bufferSize,
                virtualThreadFactory,
                ProducerType.SINGLE,
                createWaitStrategy()
        );

        // 设置事件处理器
        disruptor.handleEventsWith(messageEventHandler);

        // 启动Disruptor
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            disruptor.shutdown();
            disruptorExecutor.shutdown();
        }));
        disruptor.start();

        return disruptor.getRingBuffer();
    }

    // 计算最佳RingBuffer大小
    private int calculateRingBufferSize() {
        int cpuCores = Runtime.getRuntime().availableProcessors();
        // 经验值：根据实际场景调整
        return Math.max(1024 * 256, cpuCores * 131072);
    }

    // 根据场景选择等待策略 - 虚拟线程更适合BlockingWaitStrategy
    private WaitStrategy createWaitStrategy() {
        // 对于虚拟线程，BlockingWaitStrategy通常比BusySpinWaitStrategy更合适
        // 因为虚拟线程阻塞的成本很低
        return new BlockingWaitStrategy();
    }
}